import time
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect, HttpResponse
from app01.models import UserInfo


class ThrottleMiddleware(MiddlewareMixin):
    """
    限流中间件
        限制用户在单位时间内的访问频次，如：
            - 10分钟100次
            - 5分钟30次
            - 5秒钟/3
    """
    # 限流字典
    throttle_visits_dict = {
        # "127.0.0.1": [1645104513.2828474, 1645104512.2916808, 1645104511.529265]
    }
    # 单位时间，单位:秒
    throttle_seconds = 5
    # 单位时间内，限流的频次
    throttle_frequency = 3

    def process_request(self, request):
        # 获取到当前请求的ip地址
        remote_addr = request.META.get("REMOTE_ADDR")
        print(111, remote_addr)
        # 生成一个时间戳时间
        now = time.time()
        # 判断，如果当前请求的 remote_addr 不在throttle_visits_dict中，就添加进去
        if not self.throttle_visits_dict.get(remote_addr):
            self.throttle_visits_dict[remote_addr] = []

        history_list = self.throttle_visits_dict[remote_addr]
        # 处理history_list中无效的时间戳时间，注意两点：
        # 1. 列表不能为空，如果列表为空，表示该请求没有访问过
        # 2. 删除应该从右往左依次判断，此次请求的最新的时间戳时间 now 减去history_list[-1]中的时间戳时间，得出的结果
        #    如果大于throttle_seconds，表示改时间戳时间无效了，可以删除
        while history_list and now - history_list[-1] > self.throttle_seconds:
            history_list.pop()

        # 限制访问次数判断，在单位时间内，超过了访问频次，就不能再访问了
        if len(history_list) >= self.throttle_frequency:
            # 访问列表中，最远的时间 + 规定的单位时间 - 当前时间
            t = history_list[-1] + self.throttle_seconds - now
            return HttpResponse("<h3>访问太频繁了，请于[<span style='color:red;'>{:.2f}</span>]秒之后再来</h3>".format(t))
        # 将当前时间戳时间添加到remote_addr对应的列表中去
        history_list.insert(0, now)


class AuthMiddleware(MiddlewareMixin):
    """
    用户认证中间件，只允许登录用户访问， 否则拦截并让其跳转到 登录 页面
    """
    # 白名单
    white_list = ['/login/', '/register/']

    def process_request(self, request):
        current_path = request.path
        # 不在白名单中的都需要进行用户认证校验
        if current_path not in self.white_list:
            # 进行校验,方式1，根据用户名查数据库进行校验
            # user_obj = UserInfo.objects.filter(user=request.session.get("user")).first()
            # if not user_obj:
            #     return redirect('/login/')

            # 方式2，根据session中的is_login进行校验
            if not request.session.get("is_login"):
                return redirect('/login/')
